package com.hzy.aop;

import com.alibaba.fastjson.JSON;
import com.hzy.infrastructure.SpringUtils;
import com.hzy.infrastructure.Tools;
import com.hzy.infrastructure.config.AdminAppConfig;
import com.hzy.infrastructure.filter.HttpRequestWrapper;
import com.hzy.system.domain.SysOperationLog;
import com.hzy.system.service.ISysOperationLogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 * 接口日志操作
 */
@Aspect
@Order(5)
@Component
public class WebLogAspect {

    ThreadLocal<Long> startTime = new ThreadLocal<>();
    ThreadLocal<SysOperationLog> sysOperationLogThreadLocal = new ThreadLocal<>();

    @Pointcut("execution(public * com.hzy.admin.controller..*.*(..))")
    public void webLog() {
    }

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (Objects.isNull(attributes)) {
            return;
        }

        AdminAppConfig adminAppConfig = SpringUtils.getBean(AdminAppConfig.class);
        //判断是否记录操作日志
        if (!adminAppConfig.getDbLog()) {
            return;
        }

        startTime.set(System.currentTimeMillis());
        HttpServletRequest request = attributes.getRequest();

        /**
         * 客户端是以UTF-8编码传输数据到服务器端的，所以需要设置服务器端以UTF-8的编码进行接收，否则对于中文数据就会产生乱码
         */
        request.setCharacterEncoding("UTF-8");
        String ip = Tools.getRemoteIp(request);
        String api = request.getServletPath();
        String form = JSON.toJSONString(request.getParameterMap());
        String queryString = request.getQueryString();
        String formBody = "";

        if (request instanceof HttpRequestWrapper) {
            HttpRequestWrapper httpRequest = ((HttpRequestWrapper) request);
            formBody = Tools.getJsonStringByBody(httpRequest);
        }
        SysOperationLog sysOperationLog = new SysOperationLog();
        sysOperationLog.setIp(ip);
        sysOperationLog.setApi(api);
        sysOperationLog.setForm(form);
        sysOperationLog.setQueryString(queryString);
        sysOperationLog.setFormBody(formBody);
        sysOperationLog.setClientInfo(request.getHeader("user-agent"));
        sysOperationLogThreadLocal.set(sysOperationLog);
    }

    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        AdminAppConfig adminAppConfig = SpringUtils.getBean(AdminAppConfig.class);
        //判断是否记录操作日志
        if (!adminAppConfig.getDbLog()) {
            return;
        }

        SysOperationLog sysOperationLog = sysOperationLogThreadLocal.get();
        if (Objects.isNull(sysOperationLog)) {
            return;
        }
        sysOperationLog.setTakeUpTime(System.currentTimeMillis() - startTime.get());
        ISysOperationLogService sysOperationLogService = SpringUtils.getBean(ISysOperationLogService.class);
        sysOperationLogService.saveLog(sysOperationLog);
    }


}